/*
 * Copyright 2014 alexpad@gmail.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package alexpad.karaokarc.gui;

import alexpad.karaokarc.*;
import alexpad.karaokarc.gui.nameChooser.*;
import alexpad.karaokarc.gui.songList.*;
import alexpad.karaokarc.i18n.*;
import alexpad.karaokarc.midi.*;
import alexpad.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

/**
 *
 * @author alexpad@gmail.com
 */
public class MainFrame extends JFrame implements ActionListener{

	public static final String APP_TITLE = "Karaokarc!";
	public static final String APP_VERSION = "v1.0";
	public static final String APP_FULL_NAME = APP_TITLE + " " + APP_VERSION;

	public static final int FRAME_DEFAULT_WIDTH = 800;
	public static final int FRAME_DEFAULT_HEIGHT = 600;

	private Config config;
	private static final String MIDI_ARCHIVE_FILE_NAME = "karaokarc.archive.ser";
	private static final String CONFIG_FILE_NAME = "karaokarc.config";
	
	private SongListPanel songListPanel;
	private JFileChooser fileChooser;
	
	private MidiArchive midiArchive;
	private final File midiArchiveFile = new File(MIDI_ARCHIVE_FILE_NAME);
	
	public MainFrame() {
		loadConfig();
		initComponents();
		setTitle(APP_FULL_NAME);
		setVisible(true);
	}

	public void go() throws Throwable {
		try{
			File midiArchiveFile = new File(MIDI_ARCHIVE_FILE_NAME);
			midiArchive = MidiArchive.load(midiArchiveFile);
			if(midiArchive==null || !midiArchive.getArchiveDir().isDirectory()){
				midiArchive = null;
				chooseMidiArchive();
			}
			else if(midiArchive.isChanged()){
				// va ricreato aggiornando solo le differenze
				updateMidiArchive(midiArchive);
			}
			else{
				songListPanel.setup(midiArchive);
			}
		}
		catch(Throwable t){
			DialogHelper.showError(this, t, true);
			throw t;
		}
	}
	
	private void importMidi() {
		try{
			fileChooser.setDialogTitle("Scegli la cartella che contiene i midi da importare");
			fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
			fileChooser.setCurrentDirectory(FileUtil.getFirstExistingDir(config.getProperty(Config.IMPORT_MIDI_LAST_DIR)));
			if(fileChooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION){
				File file = fileChooser.getSelectedFile();
				if(file.isFile()) file = file.getParentFile();
				config.setProperty(Config.IMPORT_MIDI_LAST_DIR, file.getAbsolutePath());
				importMidi(file);
			}
		}
		catch(Throwable t){
			DialogHelper.showError(this, t, true);
		}
	}
	
	private TreeMap<String, Object> artistMap;
	
	private void importMidi(File sourceDir) {
		File[] midiFiles = MidiUtil.listMidiFiles(sourceDir);
		if(midiFiles==null || midiFiles.length==0){
			DialogHelper.showWarning(this, I18N.getString("generic.file.noMidiFilesFoundInDir", sourceDir.getAbsolutePath()));
			return;
		}
		artistMap = getArtistMap();
		for(File file : midiFiles){
			if(importMidiFile(file)) return;
		}
		DialogHelper.showInfo(this, I18N.getString("generic.file.noMoreMidiFilesToProcessInDir", sourceDir.getAbsolutePath()));
	}
	
	private boolean importMidiFile(File file) {
		
		NameChooserResult result = NameChooserDialog.showDialog(this, file.getName());
		System.out.print(result);
		
		switch(result.getAction()){
			case CONFIRMED:
			break;
			case SKIPPED:
			break;
			default:
				return true;
		}
		return false;
	}
	
	private void chooseMidiArchive() {
		try{
			fileChooser.setDialogTitle("Scegli la cartella archivio");
			fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
			//fileChooser.setFileFilter(MidiUtil.swingFileFilterMidiAndFolders);
			if(fileChooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION){
				File file = fileChooser.getSelectedFile();
				if(file.isFile()) file = file.getParentFile();
				midiArchive = MidiArchive.create(file);
				midiArchive.save(midiArchiveFile);
				songListPanel.setup(midiArchive);
			}
		}
		catch(Throwable t){
			DialogHelper.showError(this, t, true);
		}
	}
	
	private void updateMidiArchive(MidiArchive oldMidiArchive) {
		midiArchive = MidiArchive.copy(oldMidiArchive);
		midiArchive.save(midiArchiveFile);
		songListPanel.setup(midiArchive);
	}

	private void initComponents() {
		int width = config.getProperty(Config.MAIN_FRAME_WIDTH, FRAME_DEFAULT_WIDTH);
		int height = config.getProperty(Config.MAIN_FRAME_HEIGHT, FRAME_DEFAULT_HEIGHT);

		setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
		setResizable(true);
		setPreferredSize(new Dimension(width, height));
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				exit();
			}
		});
		Dimension screenDim = this.getToolkit().getScreenSize();

		Integer posX = config.getProperty(Config.MAIN_FRAME_POSX, (Integer) null);
		Integer posY = config.getProperty(Config.MAIN_FRAME_POSY, (Integer) null);

		if (posX == null || posY == null) {
			setBounds((int) (screenDim.getWidth() - width) / 2, (int) (screenDim.getHeight() - height) / 2, width, height);
		}
		else {
			setBounds(posX, posY, width, height);
		}

		setIconImage(this.getToolkit().createImage(getClass().getResource("/alexpad/karaokarc/img/icon.png")));
		
		songListPanel = new SongListPanel();
		getContentPane().add(songListPanel);
		
		File file = new File(config.getProperty(Config.OPENED_DIR, System.getProperty("user.home")));
		fileChooser = new JFileChooser(file);
		
		initMenuBar();	
	}
	
	
	private JMenuItem archiveFolderMenu;
	private JMenuItem importMidiMenu;
	
	private void initMenuBar(){
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu menu = new JMenu("File");
		menuBar.add(menu);
		archiveFolderMenu = new JMenuItem("Cartella archivio");
		archiveFolderMenu.setToolTipText("Seleziona la cartella di archiviazione dei file midi...");
		archiveFolderMenu.addActionListener(this);
		menu.add(archiveFolderMenu);
		
		importMidiMenu = new JMenuItem("Importa midi");
		importMidiMenu.setToolTipText("Aggiungi nuovi midi file all'archivio...");
		importMidiMenu.addActionListener(this);
		menu.add(importMidiMenu);
		
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if(source==archiveFolderMenu){
			chooseMidiArchive();
		}
		else if(source==importMidiMenu){
			importMidi();
		}
	}

	public void exit() {
		if(DialogHelper.showYesNoQuestion(this, I18N.getString("exit.question"), DialogHelper.OPTION_NO)==DialogHelper.OPTION_YES){
			saveConfig();
			System.exit(0);
		}
	}

	public void saveConfig() {
		try {
			config.setProperty(Config.MAIN_FRAME_WIDTH, getWidth());
			config.setProperty(Config.MAIN_FRAME_HEIGHT, getHeight());
			config.setProperty(Config.MAIN_FRAME_POSX, (int) getBounds().getX());
			config.setProperty(Config.MAIN_FRAME_POSY, (int) getBounds().getY());
			config.save();
		}
		catch (Throwable t) {
			t.printStackTrace();
		}
	}

	public void loadConfig() {
		File file = new File(CONFIG_FILE_NAME);
		config = new Config(file);
		if (file.exists()) {
			try {
				config.load();
			}
			catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}

	public Config getConfig() {
		return config;
	}

	private TreeMap<String, Object> getArtistMap() {
		TreeMap<String, Object> map = new TreeMap();
		String key;
		for(MidiSongInfo item : midiArchive.getInfosAsList()){
			key = item.getArtist();
			if(map.containsKey(key)) continue;
			map.put(key, key);
		}
		return map;
	}

}
